package com.fowo.api.tiktok.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.datainterface.constants.Constants;
import com.fowo.api.datainterface.entity.DatainterfaceAuthority;
import com.fowo.api.datainterface.service.DatainterfaceAuthorityService;
import com.fowo.api.datainterface.util.Common;
import com.fowo.api.entity.ShopInfo;
import com.fowo.api.model.shop.info.ShopInfoVo;
import com.fowo.api.service.impl.ShopInfoServiceImpl;
import com.fowo.api.tiktok.util.TiktokUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
@Slf4j
public class TiktokAuthService {
    @Resource
    private DatainterfaceAuthorityService datainterfaceAuthorityBaseService;
    @Resource
    private Common common;
    @Resource
    private ShopInfoServiceImpl shopInfoService;

    public static final String GET_AUTHORIZED_URL = "/authorization/202309/shops";
//    public static final String GET_AUTHORIZED_URL = "/api/shop/get_authorized_shop";


    public String getAuthorizateUrl(String state) throws Exception {
//        model.setPlatform("TikTok");
//        Long shopId = shopInfoService.create(model);

        DatainterfaceAuthority entityAuthority = datainterfaceAuthorityBaseService.getOne(Wrappers.<DatainterfaceAuthority>lambdaQuery().eq(DatainterfaceAuthority::getAppCode,"TikTok"), false);
        //跳转鉴权路径
        String authUrl = common.getAuthoritySimpleFactory(entityAuthority, "authUrl");

        String serviceId = common.getAuthoritySimpleFactory(entityAuthority, "serviceId");

        //拼接
        String url = authUrl + "?service_id=" + serviceId + "&state=" + state;
        return url;
    }

    public void getToken(String code, String state){
        DatainterfaceAuthority entityAuthority = datainterfaceAuthorityBaseService.getOne(Wrappers.<DatainterfaceAuthority>lambdaQuery().eq(DatainterfaceAuthority::getAppCode,"TikTok"), false);

        String domain = common.getAuthoritySimpleFactory(entityAuthority, "domain");
        String path = common.getAuthoritySimpleFactory(entityAuthority, "getTokenPath");
        String appKey = common.getAuthoritySimpleFactory(entityAuthority, "appKey");
        String appSecret = common.getAuthoritySimpleFactory(entityAuthority, "appSecret");

        String url = domain+path+"?app_key="+appKey+"&app_secret="+appSecret+"&auth_code="+code+"&grant_type=authorized_code";
        Object result = TiktokUtil.getBaseAspect().httpRequest(url, HttpMethod.GET, null, null, Object.class, Constants.EBOEXP_TOKEN, StrUtil.EMPTY);

        JSONObject body = JSONUtil.parseObj(result);
        log.error("店铺授权返回参数：{}",JSONUtil.toJsonStr(body));
        JSONObject resultObject = JSONUtil.parseObj(body);
        Integer resultCode = resultObject.getInt("code");

        String shopName = state.replaceFirst("NAME_","");
        ShopInfo shopInfo = new ShopInfo();
        shopInfo.setShopName(shopName);
        shopInfo.setPlatform("TikTok");
        shopInfo.setCreateTime(new Date());

        if(resultCode == 0){
            JSONObject data = resultObject.getJSONObject("data");
            shopInfo.setAuthTime(new Date());
            shopInfo.setUpdateAuthTime(new Date());
            shopInfo.setSellerAuthStatus("SQ01");
            shopInfo.setRefreshToken(data.getStr("access_token"));
            shopInfo.setTiktokRefreshToken(data.getStr("refresh_token"));
            shopInfo.setMarketplaceId(getAuthorizedShops(shopInfo));
        }else{
            shopInfo.setSellerAuthStatus("SQ02");
            shopInfo.setErrorAuthTime(new Date());
        }
        shopInfo.setLastUpdateTime(new Date());
        shopInfoService.save(shopInfo);

    }

    /**
     * 重新授权
     * @param shopId
     */
    public void refreshToken(Long shopId){
        DatainterfaceAuthority entityAuthority = datainterfaceAuthorityBaseService.getOne(Wrappers.<DatainterfaceAuthority>lambdaQuery().eq(DatainterfaceAuthority::getAppCode,"TikTok"), false);

        String domain = common.getAuthoritySimpleFactory(entityAuthority, "domain");
        String path = common.getAuthoritySimpleFactory(entityAuthority, "refreshTokenPath");
        String appKey = common.getAuthoritySimpleFactory(entityAuthority, "appKey");
        String appSecret = common.getAuthoritySimpleFactory(entityAuthority, "appSecret");

        final ShopInfo shopInfo = shopInfoService.getById(shopId);
        String url = domain+path+"?app_key="+appKey+"&app_secret="+appSecret+"&refresh_token="+shopInfo.getTiktokRefreshToken()+"&grant_type=refresh_token";
        Object result = TiktokUtil.getBaseAspect().httpRequest(url, HttpMethod.GET, null, null, Object.class, Constants.EBOEXP_TOKEN, StrUtil.EMPTY);

        JSONObject body = JSONUtil.parseObj(result);
        log.error("店铺重新授权返回参数：{}",JSONUtil.toJsonStr(body));
        JSONObject resultObject = JSONUtil.parseObj(body);
        Integer resultCode = resultObject.getInt("code");
        if(resultCode == 0){
            JSONObject data = resultObject.getJSONObject("data");

            shopInfo.setAuthTime(new Date());
            shopInfo.setUpdateAuthTime(new Date());
            shopInfo.setSellerAuthStatus("SQ01");
            shopInfo.setRefreshToken(data.getStr("access_token"));
            shopInfo.setTiktokRefreshToken(data.getStr("refresh_token"));
        }else{
            shopInfo.setSellerAuthStatus("SQ02");
            shopInfo.setErrorAuthTime(new Date());
        }
        shopInfoService.updateById(shopInfo);
    }

    public String getAuthorizedShops(ShopInfo shopInfo){
        DatainterfaceAuthority entityAuthority = datainterfaceAuthorityBaseService.getOne(Wrappers.<DatainterfaceAuthority>lambdaQuery().eq(DatainterfaceAuthority::getAppCode,"TikTok"), false);
        String rootPath = entityAuthority.getRootPath();
        String appKey = common.getAuthoritySimpleFactory(entityAuthority, "appKey");
        String appSecret = common.getAuthoritySimpleFactory(entityAuthority, "appSecret");

        HttpHeaders header = new HttpHeaders();
        header.set("Content-Type", "application/json");
        header.set("x-tts-access-token", shopInfo.getRefreshToken());

        Long timestamp = System.currentTimeMillis()/1000;
//        String input = "app_key"+appKey+"timestamp"+timestamp;
        Map<String,Object> query = new TreeMap<>();
        query.put("access_token",shopInfo.getRefreshToken());
        query.put("app_key",appKey);
        query.put("timestamp",timestamp);

        String sign = TiktokUtil.getSign(appSecret,GET_AUTHORIZED_URL,query,null);
        query.put("sign",sign);

//        String pathParam = "?access_token="+shopInfo.getRefreshToken()+"&app_key="+appKey+"&timestamp="+timestamp+"&sign="+sign;
        StringBuilder pathParam = new StringBuilder();
        for(String key : query.keySet()){
            pathParam.append("&").append(key).append("=").append(query.get(key));
        }
        String url = rootPath + GET_AUTHORIZED_URL + "?" + pathParam.substring(1);

        Object result = TiktokUtil.getBaseAspect().httpRequest(url, HttpMethod.GET, null, header, Object.class, Constants.Read, StrUtil.EMPTY);

        JSONObject body = JSONUtil.parseObj(result);
        log.info("获取授权店铺："+body.toString());
        Integer code = body.getInt("code");
        if(code == 0){
            JSONObject data = body.getJSONObject("data");
            JSONArray shops = data.getJSONArray("shops");
            final JSONObject shop = shops.getJSONObject(0);
            return shop.getStr("cipher");
        }
        return null;
    }

    public void refreshAuthorized(){
        final List<ShopInfo> list = shopInfoService.list(Wrappers.lambdaQuery(ShopInfo.class)
                .eq(ShopInfo::getPlatform,"TikTok")
                .eq(ShopInfo::getSellerAuthStatus,"SQ01"));
        for(ShopInfo shopInfo : list){
            try{
                refreshToken(shopInfo.getId());
            }catch (Exception e){
                log.error("店铺{}更新授权失败",shopInfo.getId());
            }
        }
    }
}
